#include "resource_file.h"
#include "resman.h"

#include "num/crc32.h"
#include "util/mmgr.h"		    // Needs to come in early
#include "util/log.h"		    // Needs to come in early

// VFS
#include "vfs/vfs.h"


#include "file_tracker.h"

#include <algorithm>

using namespace res;

ResourceFile::ResourceFile() :
	m_ID(0),
	m_Size(0),
	m_State(RS_NEW),
	m_RefCount(0),
	m_LastAccessed(0),
	m_FileType(RES_UNKNOWN)
{

}

ResourceFile::~ResourceFile()
{
	
}

/// load resource into RAM.
void ResourceFile::CacheResource()
{
	m_State = RS_LOADING;
	// load from the VFS.

	vfs::VFS& FileSys = vfs::VFS::Instance();

	if (!FileSys.GetFile(m_Path, m_Data))
	{
		_LOG(MSG_ERROR, "Unable to load surface " << m_Name);
		m_State = RS_FAILED;
		return;
	}

	// data is in.
	m_State = RS_CACHED;

	// this could be done in a seperate thread later ?
    // CHIT: IOS doesn't like loading into texture immediately    
    if(res::ResMan::Instance().IsForceSkipInit() == false)
        InitializeResource();
}

bool ResourceFile::Load(const std::string& _File)
{

	m_Name = _File;
	std::transform(m_Name.begin(), m_Name.end(), m_Name.begin(), tolower);
	m_Path = vfs::VFS::Instance().GetPath(_File);
	m_Extension = m_Name.substr( m_Name.find_last_of( "." ) + 1 );	// store extension as lowercase
	std::transform(m_Extension.begin(), m_Extension.end(), m_Extension.begin(), tolower);


	if (m_Path.empty())
	{
		_LOG(MSG_WARNING, "Unable to find resource " << _File);
		return false;
	}

	m_ID = num::CRC32::FastHash(_File.c_str(), true);
	CacheResource();
	if (m_State == RS_FAILED) return false;

	// Tell the system to reload it later
#ifdef FILE_TRACKER_ACTIVE
	FileTracker::Instance().StartTrackingFile(_File, this);
#endif

	// check if the file's valid ?
	return true;
}

void	ResourceFile::FromMemory(unsigned char* pData, unsigned int	Size)
{
	m_Name	= "FROM_MEMORY";
	m_Path = "MEMORY";
	m_Extension = "";

	m_ID = 0;

	m_Data.DataArray = new unsigned char[Size];
	memcpy(m_Data.DataArray, pData, Size);	// do we need to copy/cache this?	Probably.
	m_Data.Size = Size;
	m_Data.Index = 0;
	m_Data.FileName = m_Name;

	m_State = RS_CACHED;
}